package com.shujia.wyh.day15;

/*
    生产者消费者模型：
    生产者线程：对学生对象进行赋值操作
    消费者线程：将赋值后的学生对象中的成员变量值取出
    共享数据：学生对象
    测试类：WaitDemo1

    问题1：我们按照所分析的成员编写类后发现，运行的结果是null---0 这个结果是必然的
        原因是我们的生产者线程和消费者线程自己内部都有一个独立的学生对象，而我们的消费者和生产者应该是共享一个学生对象
        解决方案：只需要在外部创建出学生对象即可，使用构造方法传入每个线程中

    问题2：我们将学生对象在外部创建，使用构造方法传入的时候，运行程序，依旧会偶尔出现null---0的现象
        为了程序观察更加明显，我们加入了死循环和if判断，让它赋不同的值，出现了姓名和年龄错位的现象
        同时满足3个条件：
            1、是否具备多线程环境？ 是，一个生产者线程，一个消费者线程
            2、是否存在共享数据？  是，student
            3、是否有多条语句操作着共享数据？ 是。
        该程序就存在线程安全的问题。
        解决方法：synchronized同步代码块解决

    问题3：生产者生产了一次数据之后，消费者消费了很多次，这个现象不符合生产者消费者模型
        生产者：在生产数据（赋值）之前，应该先看一看数据有没有被消费（取值），如果被消费了就生产数据，如果没有被消费，就等待并通知消费者消费数据。
        消费者：在消费数据之前，应该先看一看数据有没有生产出来，如果已经生产了就消费数据，如果还没有生产，就等待并通知生产者生产数据。
        解决方案：加入了等待唤醒机制


   提升练习：
        生产者：是存钱用户线程
        消费着：是取钱用户线程  （进阶练习1：多个消费者，进阶练习2：消费者自身也可以生产）
        共享数据：银行卡



 */
public class WaitDemo1 {
    public static void main(String[] args) {
        Student student = new Student();

        //创建生产者线程
        ProducerThread p1 = new ProducerThread(student);

        //创建消费者线程
        ConsumerThread c1 = new ConsumerThread(student);

        //启动线程
        p1.start();
        c1.start();

    }
}
